#include "unitResource.h"

int UnitResource::load(int rsc_num, char* output_path) {
  m_rsc_num = rsc_num;
  memset(&m_head, sizeof(unit_head_t), 0);
  m_head.rsc_num = m_rsc_num;
  m_head.off = (uint32_t*)malloc(sizeof(uint32_t) * rsc_num);
  assert(m_head.off);
  m_head.len = (uint32_t*)malloc(sizeof(uint32_t) * rsc_num);
  assert(m_head.len);
  sprintf(m_output_path, output_path);

  char fname[NAME_LEN];
  sprintf(fname, "%s/%s.0", m_output_path, UNIT_NAME);
  ofp = fopen(fname, "w");
  if(ofp == NULL) {
    FATAL("fopen [%s] error", fname);
    return E_RET;
  }


  return S_RET;
}

void UnitResource::append_unit(char* s, int i) {
  //NOTICE("append[%s], [%d]", s, i);
  m_item[i] = s;
}

void UnitResource::serialize(uint32_t id) {
  int ret;
  uint32_t tlen;
  unit_head_t* phead = &m_head;
  uint32_t toff = 0;
  uint32_t len;

  tlen = 0;
  for(int i = 0 ; i < m_rsc_num ; ++i) {
    if(strlen(m_item[i]) >= MAX_UNIT_SIZE)
      tlen+=(MAX_UNIT_SIZE + 1);
    else
      tlen+=(strlen(m_item[i]) + 1);
  }
  phead->tlen = tlen;
  ret = fwrite(&phead->tlen, sizeof(uint32_t), 1, ofp);
  assert(ret == 1);

  ret = fwrite(&id, sizeof(uint32_t), 1, ofp);
  assert(ret == 1);

  ret = fwrite(&phead->rsc_num, sizeof(uint32_t), 1, ofp);
  assert(ret == 1);

  for(int i = 0 ; i < m_rsc_num ; ++i) {
    if(strlen(m_item[i]) > MAX_UNIT_SIZE)
      len = MAX_UNIT_SIZE + 1;
    else
      len = strlen(m_item[i]) + 1;

    phead->off[i] = toff;
    toff+=len;

    ret = fwrite(&phead->off[i], sizeof(uint32_t), 1, ofp);
    assert(ret == 1);

    ret = fwrite(&len, sizeof(uint32_t), 1, ofp);
    assert(ret == 1);

  }

  char Z='\0';

  for(int i = 0 ; i < m_rsc_num ; ++i) {
    if(strlen(m_item[i]) > MAX_UNIT_SIZE) {
      ret = fwrite(m_item[i], MAX_UNIT_SIZE, 1, ofp);
      assert(ret == 1);
    }
    else {
      ret = fwrite(m_item[i], strlen(m_item[i]), 1, ofp);
      assert(ret == 1);
    }

    ret = fwrite(&Z, 1, 1, ofp);
    assert(ret == 1);
  }

}

void UnitResource::reset() {
  for(int i = 0 ; i < MAX_RSC_NUM ; ++i) {
    m_item[i] = NULL;
  }
}

void UnitResource::chg_file(int fid) {
  char fname[NAME_LEN];
  fclose(ofp);
  sprintf(fname, "%s/%s.%d",
      m_output_path,
      UNIT_NAME,
      fid);
  ofp = fopen(fname, "w");
  if(ofp == NULL) {
    FATAL("fopen [%s] error", fname);
    assert(0);
  }
}




